package repository

import (
	"context"

	"server/internal/app/dto"
	"server/internal/app/model"
	"server/internal/core/store"

	"gorm.io/gorm"
)

type SysAdminRepository struct {
	db *gorm.DB
}

func NewSysAdminRepository() *SysAdminRepository {
	return &SysAdminRepository{
		db: store.DB,
	}
}

func (r *SysAdminRepository) GetByID(ctx context.Context, id uint) (*model.SysAdmin, error) {
	var admin model.SysAdmin
	if err := r.db.WithContext(ctx).First(&admin, id).Error; err != nil {
		return nil, err
	}
	return &admin, nil
}

func (r *SysAdminRepository) GetByUsername(ctx context.Context, username string) (*model.SysAdmin, error) {
	var admin model.SysAdmin
	if err := r.db.WithContext(ctx).Where("username = ?", username).First(&admin).Error; err != nil {
		return nil, err
	}
	return &admin, nil
}

func (r *SysAdminRepository) GetByEmail(ctx context.Context, email string) (*model.SysAdmin, error) {
	var admin model.SysAdmin
	if err := r.db.WithContext(ctx).Where("email = ?", email).First(&admin).Error; err != nil {
		return nil, err
	}
	return &admin, nil
}

func (r *SysAdminRepository) List(ctx context.Context, param *dto.PaginationRequest) (*dto.PaginationResponse[model.SysAdmin], error) {
	query := r.db.WithContext(ctx).Model(&model.SysAdmin{})
	if param.Keyword != "" {
		query = query.Where("username LIKE ? OR nickname LIKE ? OR email LIKE ?", "%"+param.Keyword+"%", "%"+param.Keyword+"%", "%"+param.Keyword+"%")
	}
	var total int64
	if err := query.Count(&total).Error; err != nil {
		return nil, err
	}
	query = query.Order("id DESC")
	query = query.Offset(param.Offset()).Limit(param.PageSize)
	var admins []model.SysAdmin
	if err := query.Find(&admins).Error; err != nil {
		return nil, err
	}
	return &dto.PaginationResponse[model.SysAdmin]{
		Total:    total,
		Page:     param.Page,
		PageSize: param.PageSize,
		Items:    admins,
	}, nil
}

func (r *SysAdminRepository) Create(ctx context.Context, admin *model.SysAdmin) error {
	return r.db.WithContext(ctx).Create(admin).Error
}

func (r *SysAdminRepository) Update(ctx context.Context, id uint, data map[string]any) error {
	return r.db.WithContext(ctx).Model(&model.SysAdmin{}).Where("id = ?", id).Updates(data).Error
}

// 获取管理员权限
func (r *SysAdminRepository) GetAdminPermissions(ctx context.Context, adminID uint) ([]model.SysAdminRolePermission, error) {
	var rolePermissions []model.SysAdminRolePermission
	if err := r.db.WithContext(ctx).Raw(`SELECT t2.code as role_code,
       t2.name as role_name,
       t4.path as permission_path,
       t4.name as permission_name,
       t4.type as permission_type
from sys_admin_role t1
         join sys_roles t2 on t1.role_id = t2.id
         join sys_role_permission t3 on t2.id = t3.role_id
         join sys_permissions t4 on t3.permission_id = t4.id
where t1.admin_id = ? 
	and t2.status = ? 
	and t4.status = ?`, adminID, model.StatusEnabled, model.StatusEnabled).Find(&rolePermissions).Error; err != nil {
		return nil, err
	}
	return rolePermissions, nil
}
